iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0
Modern Web

Angular牙起來系列 第 8

# Day08 Angular牙起來 - 程式面介紹 Typescript物件、陣列 與NgFor

  • 分享至 

  • xImage
  •  

Day08 Angular牙起來 - 程式面介紹 物件、陣列 與ngFor、ngIf

再來換到商店store區塊

商店嘛,總是要販售一些武器防具
不然裸裝的冒險者早晚都死光了

程式內的物件 Object

於是在 store.component.ts 中加入 weapon物件

我要一把小劍,他的攻擊力是5 {name: '小劍', atk: '5'}

...

export class StoreComponent implements OnInit {

  weapon = {name: '小劍', atk: '5'};

  constructor() { }

  ngOnInit(): void {
  }

}

接下來你知道的,還要修改樣板 store.component.html

<h2>商店區塊</h2>
<div>武器: {{weapon}}</div>

來看一下吧

诶?奇怪
我的小劍跟攻擊力5去哪了?
為什麼是出現[object Object]呢?

我們分別使用 alertconsole.log 印出來看看

...

export class StoreComponent implements OnInit {

  weapon = {name: '小劍', atk: '5'};

  constructor() { }

  ngOnInit(): void {
    alert(this.weapon);
    console.log(this.weapon);
  }

}

使用 alert 也一樣,印物件只會出現Object、而非物物件內部結構

使用 console.log 則可以看到物件內部結構

管線 pipe

要在Angular樣板上印出完整物件,可以使用json pipe
透過將物件轉換成json格式再印出來

修改 store.component.html

<h2>商店區塊</h2>
<div>武器: {{weapon | json}}</div>

在綁定的變數後方加上 | json ,其中這一槓 | 代表的就是管線 pipe

關於pipe元件會在之後的章節再次提及

印出物件的畫面

取得物件底下的成員

分別印出武器物件底下的 名稱 name攻擊力 atk

透過以下兩種方式都可以取得物件底下的數值

  • 物件的點點.來取得成員
  • [''] 來索引物件
<h2>商店區塊</h2>
<div>武器名稱: {{weapon.name}}</div>
<div>武器攻擊力: {{weapon['atk']}}</div>

什麼,你說現在商店只有一把武器 不夠看、太過窮酸?

看來... 我們只好導入陣列了

程式內的陣列 Array

武器變成多把,所以把變數名稱改成 weapons 複數
然後以陣列包起這個物件

修改 store.component.ts

export class StoreComponent implements OnInit {

  weapons = [
    {name: '小劍', atk: '5'},
    {name: '彎刀', atk: '7'},
    {name: '大魔劍', atk: '11'},
  ];

  constructor() { }

  ngOnInit(): void {
  }
}

因為 weapons 變成陣列型態了,所以樣板也需要加入 [0] 來索引陣列

<h2>商店區塊</h2>
<div>武器名稱: {{weapons[0].name}}</div>
<div>武器攻擊力: {{weapons[0]['atk']}}</div>

樣板中的For迴圈 - *ngFor

有三樣武器,如果要透過HTML印出來
一樣一樣指定 weapons[0]weapons[1]weapons[2] 也太麻煩了

所以Angular在樣板中也有 For 迴圈 ,叫作 *ngFor

修改 store.component.html

<h2>商店區塊</h2>
<div *ngFor="let weapon of weapons">
  <div>武器名稱: {{weapon.name}}</div>
  <div>武器攻擊力: {{weapon['atk']}}</div>
  <br>
</div>

因為迴圈需要一層空間來指定loop的範疇,所以ngFor會放在要循環結構的外面
用法為*ngFor = let ... of ...

修改後結果

迴圈的索引值 index

若想將武器商品編號,需要For迴圈中的索引值
可在 ngFor 的地方加上let ... = index,便可以引用索引編號

修改 store.component.html

<h2>商店區塊</h2>
<div *ngFor="let weapon of weapons; let i = index">
  <div>武器編號: {{i + 1}}</div>
  <div>武器名稱: {{weapon.name}}</div>
  <div>武器攻擊力: {{weapon['atk']}}</div>
  <br>
</div>

什麼,你覺得這波操作挺稀鬆平常?

拜託,這裡可是HTML樣板啊,原本可都是只寫標籤元素的地方
能在這裡寫code難道不驚訝嗎?

這都是Angular框架的功勞啊


接下來替遊戲增加一點樂趣興

因為遊戲商店中,總會有一些玩樂性質的垃圾武器出現
譬如說接下來要登場的這一把 只是名稱長了一點但沒有任何攻擊力 的武器

修改 store.component.ts

export class StoreComponent implements OnInit {

  weapons = [
    {name: '小劍', atk: '5'},
    {name: '彎刀', atk: '7'},
    {name: '大魔劍', atk: '11'},
    {name: '只是名稱長了一點但沒有任何攻擊力'},
  ];

  constructor() { }

  ngOnInit(): void {
  }
}

結果畫面

樣板中的if判斷 - *ngIf

因為 只是名稱長了一點但沒有任何攻擊力 這把武器真的沒有攻擊力的屬性
我想將他的 武器攻擊力 這一行隱藏掉,不然顯示在那也頗怪、挺佔位置的

這時候可以用if 判斷式 *ngIf

修改 store.component.html

<h2>商店區塊</h2>
<div *ngFor="let weapon of weapons; let i = index">
  <div>武器編號: {{i + 1}}</div>
  <div>武器名稱: {{weapon.name}}</div>
  <div *ngIf="weapon.atk">武器攻擊力: {{weapon['atk']}}</div>
  <br>
</div>

weapon 底下有 atk 這個屬性時,才會顯示武器攻擊力這一行

完成畫面

*ngIf 也可以有其他篩選條件
譬如過濾武器,只顯示攻擊力為11的武器

<h2>商店區塊</h2>
<div *ngFor="let weapon of weapons; let i = index">
  <div *ngIf="weapon.atk == '11'">
    <div>武器編號: {{i + 1}}</div>
    <div>武器名稱: {{weapon.name}}</div>
    <div *ngIf="weapon.atk">武器攻擊力: {{weapon['atk']}}</div>
    <br>
  </div>
</div>

這邊的'11'因為是字串而非數字,所以用單引號''括起來

最終完成畫面


恭喜到這一步已經完成 61% 的Angular

至於ngFor、ngIf為什麼要有那個星號*
因為星號表示循環結構的語法糖

另外,ngIf跟ngFor沒辦法綁在同一個標籤上


上一篇
# Day07 Angular牙起來 - 程式面介紹 繫結綁定2 小括號綁定法
下一篇
# Day09 Angular牙起來 - 程式面介紹 繫結綁定3 中括號綁定法
系列文
Angular牙起來30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言